package com.steven.forum.service

import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.steven.forum.dao.ComplainDao
import com.steven.forum.dao.ForumDao
import com.steven.forum.utils.*
import com.steven.forum.utils.ForumConstants.A_PAGE_MAX_ITEM
import com.steven.forum.utils.ForumConstants.KEY_FORUM_DISCUSS_LIST
import com.steven.forum.utils.ForumConstants.KEY_FORUM_FID
import com.steven.forum.utils.ForumConstants.KEY_HOT_FORUM_LIST
import com.steven.forum.utils.ForumConstants.KEY_NEW_FORUM_LIST
import com.steven.forum.utils.ResultUtils.SELECT_ERROR
import com.steven.forum.utils.ResultUtils.SUCCESS_CODE
import com.steven.forum.utils.ResultUtils.UPDATE_ERROR
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.*
import java.util.concurrent.TimeUnit
import javax.servlet.http.HttpServletResponse

@Service
class ForumServiceImp : ForumService {
    @Autowired
    var forumDao: ForumDao? = null

    @Autowired
    var complainDao: ComplainDao? = null

    @Autowired
    var redisUtil: RedisUtil? = null

    override fun queryHotForumList(uid: Long?, page: Long): JSONObject {
        val jsonObject = JSONObject()
        val key = KEY_HOT_FORUM_LIST + page
        if (redisUtil?.exists(key) == true) {
            jsonObject["list"] = redisUtil?.get(key)
        } else {
            val forumList = forumDao?.queryHotForumList(uid, getPageEnd(page))
            redisUtil?.set(key, forumList, 10, TimeUnit.SECONDS)
            jsonObject["list"] = forumList
        }
        jsonObject["msg"] = "success"
        return makeRes(0, jsonObject)
    }

    override fun queryNewForumList(uid: Long?, page: Long): JSONObject {
        val jsonObject = JSONObject()
        val key = KEY_NEW_FORUM_LIST + page
        if (redisUtil?.exists(key) == true) {
            jsonObject["list"] = redisUtil?.get(key)
        } else {
            val forumList = forumDao?.queryNewForumList(uid, getPageEnd(page))
            redisUtil?.set(key, forumList, 10, TimeUnit.SECONDS)
            jsonObject["list"] = forumList
        }
        jsonObject["msg"] = "success"
        return makeRes(0, jsonObject)
    }

    override fun queryForumByFid(uid: Long?, fid: Long?): JSONObject {
        val jsonObject = JSONObject()
        if (fid == null) {
            jsonObject["msg"] = "请求错误"
            return makeRes(0, jsonObject)
        }
        val key = KEY_FORUM_FID + fid
        try {
            jsonObject["info"] = if (redisUtil?.exists(key) == true) {
                redisUtil?.get(key)
            } else {
                val forumInfo = forumDao?.queryForumByFid(fid)?.get(0)
                redisUtil?.set(key, forumInfo)
                forumInfo
            }
            val iconUrl = forumDao?.queryUserIconUrlByFid(fid)?.get(0)
            jsonObject["url"] = iconUrl
            jsonObject["msg"] = "success"
        } catch (e: Exception) {
            jsonObject["msg"] = e.message
        }
        return makeRes(0, jsonObject)
    }

    override fun addForum(uid: Long?, title: String?, content: String?, images: Array<MultipartFile>?, response: HttpServletResponse): JSONObject {
        val jsonObject = JSONObject()
        if (uid == null || title.isNullOrEmpty() || content.isNullOrEmpty()) {
            jsonObject["msg"] = "请求错误"
            return makeRes(0, jsonObject)
        }
        try {
            val imageJson = JSONArray()
            val currentTime = System.currentTimeMillis() / 1000
            images?.forEachIndexed { index, multipartFile ->
                if (!testFileIsRight(multipartFile)) {
                    response.sendError(500, "文件类型错误")
                }
                val imgName = uid.toString() + "_" + currentTime + "_" + index + ".jpg"
                val imgFilePath = "/root/java/forum/image/$imgName"
                //val imgFilePath = "f:/pic/$imgName"
                val out: OutputStream = FileOutputStream(imgFilePath)
                out.write(multipartFile.bytes)
                out.flush()
                out.close()
                imageJson.add(imgFilePath)
            }
            println(imageJson)
            forumDao?.addForum(uid, title, content, imageJson.toString())
            jsonObject["msg"] = "success"
            redisUtil?.remove(KEY_NEW_FORUM_LIST + 1)
        } catch (e: Exception) {
            jsonObject["msg"] = e.message
            e.printStackTrace()
        }
        return makeRes(0, jsonObject)
    }

    override fun addUserHistory(uid: Long?, forumId: Long?): JSONObject {
        val jsonObject = JSONObject()
        if (uid == null || forumId == null) {
            jsonObject["msg"] = "请求错误"
            return makeRes(0, jsonObject)
        }
        try {
            if (forumDao?.getUserHistoryByForumId(uid, forumId)?.size ?: 0 > 0) {
                if (forumDao?.updateUserHistory(uid, forumId) ?: 0 >= 1) {
                    jsonObject["msg"] = "success"
                }
            } else {
                if (forumDao?.addUserHistory(uid, forumId) ?: 0 >= 1) {
                    jsonObject["msg"] = "success"
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            jsonObject["msg"] = e.message
        }
        return makeRes(0, jsonObject)
    }

    override fun queryDiscuss(forumId: Long?): JSONObject {
        val jsonObject = JSONObject()
        if (forumId == null) {
            jsonObject["msg"] = "请求错误"
            return makeRes(0, jsonObject)
        }
        val key = KEY_FORUM_DISCUSS_LIST + "_" + forumId
        if (redisUtil?.exists(key) == true) {
            jsonObject["list"] = redisUtil?.get(key)
            jsonObject["msg"] = "success"
        } else {
            val list = forumDao?.getDiscuss(forumId)
            jsonObject["list"] = list
            jsonObject["msg"] = "success"
            redisUtil?.set(key, list, 10, TimeUnit.SECONDS)
        }
        return makeRes(0, jsonObject)
    }

    override fun addDiscuss(uid: Long?, fid: Long?, content: String?): JSONObject {
        val jsonObject = JSONObject()
        try {
            if (uid == null || fid == null || content.isNullOrEmpty()) {
                jsonObject["msg"] = "请求错误"
                return makeRes(0, jsonObject)
            }
            forumDao?.addDiscuss(uid, fid, content)
            jsonObject["msg"] = "success"
            redisUtil?.remove(KEY_FORUM_DISCUSS_LIST + "_" + fid)
            queryDiscuss(fid)
        } catch (e: Exception) {
            jsonObject["msg"] = e.message
        }
        return makeRes(0, jsonObject)
    }

    private fun getPageEnd(page: Long): Long {
        return (page - 1) * A_PAGE_MAX_ITEM + A_PAGE_MAX_ITEM - 1
    }

    private fun testFileIsRight(file: MultipartFile): Boolean {
        return if (!file.isEmpty) {
            try {
                val type: String = FileTypeUtils.getFileTypeByStream(file.bytes)
                "jpg" == type || "png" == type
            } catch (e: IOException) {
                e.printStackTrace()
                false
            }
        } else {
            false
        }
    }


    override fun addComplain(uid: Long, targetUid: Long, content: String, images: Array<MultipartFile>, response: HttpServletResponse): JSONObject {
        val jsonObject = JSONObject()
        try {
            val imageJson = JSONArray()
            val currentTime = System.currentTimeMillis() / 1000
            images.forEachIndexed { index, multipartFile ->
                if (!testFileIsRight(multipartFile)) {
                    response.sendError(500, "文件类型错误")
                }
                val imgName = uid.toString() + "_" + currentTime + "_" + index + ".jpg"
                val imgFilePath = "${
                    if (SystemUtils.isOSWin()) {
                        "f:/pic/"
                    } else if (SystemUtils.isOSLinux()) {
                        "/root/java/complain/"
                    } else {
                        throw Exception("系统类型错误")
                    }
                }$imgName";
                val out: OutputStream = FileOutputStream(imgFilePath)
                out.write(multipartFile.bytes)
                out.flush()
                out.close()
                imageJson.add(imgFilePath)
            }
            complainDao!!.addComplain(targetUid, content, imageJson.toString(), uid)
        } catch (e: Exception) {
            jsonObject["msg"] = e.message
            e.printStackTrace()
        }
        return makeRes(0, jsonObject)
    }

    override fun queryComplain(uid: Long, lastCreateTime: Long): JSONObject {
        val json = JSONObject()
        return try {
            json["data"] = complainDao!!.queryComplain(lastCreateTime)
            makeRes(SUCCESS_CODE, json)
        } catch (e: Exception) {
            json["msg"] = e.message
            e.printStackTrace()
            makeRes(SELECT_ERROR, json)
        }
    }

    override fun updateComplain(uid: Long, id: Long): JSONObject {
        val json = JSONObject()
        return try {
            complainDao!!.updateComplain(id)
            makeRes(SUCCESS_CODE, json)
        } catch (e: Exception) {
            json["msg"] = e.message
            e.printStackTrace()
            makeRes(UPDATE_ERROR, json)
        }
    }
}